package org.daochong.fastdev.funcs;

import java.sql.SQLException;

import org.daochong.fastdev.Context;
import org.daochong.fastdev.Function;
import org.daochong.fastdev.ValidataException;
import org.daochong.fastdev.util.FastDevUtils;
import org.daochong.lang.StringUtils;
import org.daochong.lang.Validata;

public class ValidataFunction implements Function {

	@Override
	public boolean is(String id) {
		return FastDevUtils.operEntity("validata", id);
	}

	@Override
	public void exec(String key, String prop, Context context) throws SQLException {
		if (StringUtils.isEmpty(prop) || context == null || !is(key) || !key.startsWith("validata."))
			return;
		if (prop.startsWith("expression:") && !context.expressionCondition(prop.substring(11))) {
			throw new RuntimeException("Validata Fail " + prop);
		}
		String op = key.substring(9).trim();
		String[] ar = prop.split(",");
		Object[] os = new Object[ar.length];
		for (int i = 0; i < ar.length; i++) {
			os[i] = context.searchValue(ar[i].trim());
		}
		Validata v = new Validata();
		if ("isNull".equals(op) || "isNotNull".equals(op) || "isInt".equals(op) || "isDouble".equals(op)
				|| "isDate".equals(op)) {
			for (int i = 0; i < os.length; i++) {
				Object o = os[i];
				boolean flag = false;
				if ("isNull".equals(op)) {
					flag = !v.isNull(o);
				} else if ("isNotNull".equals(op)) {
					flag = !v.isNotNull(o);
				} else if ("isInt".equals(op)) {
					flag = !v.isInt(o);
				} else if ("isDouble".equals(op)) {
					flag = !v.isDouble(o);
				} else if ("isDate".equals(op)) {
					flag = !v.isDate(o);
				}
				if (flag) {
					String str = ar[i].trim();
					if (str.charAt(0) == '#' && str.charAt(str.length() - 1) == '#') {
						str = "Parameter " + str.substring(1, str.length() - 1);
					}
					throw new ValidataException(20000, "Validata " + op + " Fail: " + str, str, op);
				}
			}
		} else if ("length".equals(op)) {
			if (os.length == 3 && os[0] instanceof String) {
				boolean flag = false;
				try {
					flag = v.length((String) os[0], Integer.parseInt(os[1].toString()),
							Integer.parseInt(os[2].toString()));
				} catch (Throwable e) {
					throw new ValidataException(10000, "Validata Fail " + op + " : " + prop);
				}
				if (flag) {
					String str = ar[0].trim();
					if (str.charAt(0) == '#' && str.charAt(str.length() - 1) == '#') {
						str = "Parameter " + str.substring(1, str.length() - 1);
					}
					throw new ValidataException(20000, "Validata length Fail: " + str, str, "length");
				}
			}
		} else if ("between".equals(op)) {
			if (os.length == 3 && os[0] instanceof String) {
				boolean flag = false;
				try {
					flag = v.between(os[0], os[1], os[2]);
				} catch (Throwable e) {
					throw new ValidataException(10000, "Validata Fail " + op + " : " + prop);
				}
				if (flag) {
					String str = ar[0].trim();
					if (str.charAt(0) == '#' && str.charAt(str.length() - 1) == '#') {
						str = "Parameter " + str.substring(1, str.length() - 1);
					}
					throw new ValidataException(20000, "Validata between Fail: " + str, str, "between");
				}
			}
		} else if ("in".equals(op)) {
			if (os.length > 2) {
				boolean flag = false;
				try {
					Object[] o = new Object[os.length - 1];
					for (int i = 1; i < os.length; i++) {
						o[i - 1] = os[i];
					}
					flag = v.in(os[0], o);
				} catch (Throwable e) {
					throw new ValidataException(10000, "Validata Fail " + op + " : " + prop);
				}
				if (flag) {
					String str = ar[0].trim();
					if (str.charAt(0) == '#' && str.charAt(str.length() - 1) == '#') {
						str = "Parameter " + str.substring(1, str.length() - 1);
					}
					throw new ValidataException(20000, "Validata in Fail: " + str, str, "between");
				}
			}
		} else {
			if (!Validata.condition(op, os)) {
				throw new ValidataException(10000, "Validata Fail " + op + " : " + prop);
			}
		}
	}

}
